Skip to content

feat(hris): bind Employment to employing legal organization - #141

Draft
seonghobae wants to merge 50 commits into
developfrom
feat/employment-employing-organization
Draft

feat(hris): bind Employment to employing legal organization#141
seonghobae wants to merge 50 commits into
developfrom
feat/employment-employing-organization

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Buyer-visible HRIS core

This branch retains a valid Employment→employing legal Organization feature: one tenant-qualified, bitemporal legal-employer relationship is modeled independently from Position and Assignment, with correction-not-rewrite history, legal-entity classification, RLS/tenant integrity, and organization-specific authorization evidence. Payroll, withholding, compensation, statutory-account truth, and autonomous employment decisions remain out of scope.

Current repair state

This PR is now open · Draft · non-mergeable. Exact feature head remains 8d12ee7cd05549a69c6debf5e0de0c5fc8668f33. Its recorded base/evidence belongs to predecessor develop@9e3e4847510e1e612b48474ba42b177b8ed824df, while current protected develop is eb9757f8649aaad026a9865508d9aad50c1a7a4f. The old terminal GREEN feature checks and old OpenCode/Strix failures are historical evidence only; they are not current-base merge authorization.

The branch was lowered to Draft rather than closed because its migration, API, authorization, tests, documentation, ADR, and employing-organization semantics remain valid delta that is not fully present on protected develop.

Single-writer reconciliation

#141 overlaps the active People owners on schemas/openapi.yaml, hire.py, mutation_http.py, mutations.py, postgres_hire.py, postgres_mutations.py, and Keyverse authorization files. It must not overwrite those owners from this stale feature snapshot.

Current canonical order is:

  1. fix(core): protect canonical evidence runtime types #63 integrates shared HRIS-kernel audit/runtime truth normally when its exact gates/review authorize it.
  2. fix(people): protect governed mutation runtime types #64 finishes generic People mutation/runtime + published API contract repair, including open fix(people): reject zero assignment allocation at the published HTTP contract #233. fix(people): reject zero assignment allocation at the published HTTP contract #233 currently proves that Assignment allocation 0.0000 is invalid in domain/DB but still advertised by the published OpenAPI regex.
  3. fix(authz): protect purpose-bound runtime integrity #65 non-force adopts protected fix(people): protect governed mutation runtime types #64 and reconciles its purpose-bound AuthorizationDecision validation without losing fix(people): bind mutation results to the exact commanded HR identity #229fix(people): reject zero assignment allocation at the published HTTP contract #233.
  4. feat(hris): bind Employment to employing legal organization #141 then non-force adopts the resulting protected owner truth and reapplies only its employing-legal-Organization feature delta, including its schema/API changes, tests, docs, ADR and migration.

No source copy from mutable sibling heads, destructive rebase, force-push, or early Ready transition. A future reconciliation must preserve #141 target-scope authorization and legal-employer semantics while also preserving the protected generic People/authorization invariants that land before it.

Historical feature evidence retained

Contract-first 4eb28864d563fbe9f090c729220b54b8701172ac established the original missing-migration RED. Subsequent ordinary commits added migration 0040, bitemporal/tenant/RLS constraints, application persistence, exact organization target-scope binding, manifest/provenance updates, documentation and tests. Test-only 48de15641530cdaedbe384525e5b4aa3463cf965 exposed the target-scope evidence-binding regression and the subsequent repair preserved required_target_scope_code and enforced exact organization scope before persistence.

These checks demonstrate validity of the feature delta on its historical exact head; they do not substitute for fresh checks/review after non-force adoption of current protected owner truth.

Merge gate

Not merge-ready. It requires protected-owner adoption/reconciliation, fresh exact-head Foundation/People/PostgreSQL/security workflows, zero unresolved review findings, and a qualifying independent approval. Do not self-approve, administrator-bypass, weaken required workflows, transfer predecessor evidence, or close the PR merely because its base is stale.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e15853f9-b62a-476a-a71d-7a01f4648f3a

📥 Commits

Reviewing files that changed from the base of the PR and between 138f054 and 48de156.

📒 Files selected for processing (6)
  • .github/workflows/employment-employing-organization-quality.yml
  • manifest.json
  • packages/keyverse-adapter/src/orgmetra_keyverse_adapter/authorization.py
  • packages/keyverse-adapter/tests/test_target_scope_denial_guidance.py
  • services/people-api/tests/test_employing_organization_authorization_binding.py
  • tests/test_employment_employing_organization_postgres.sh
💤 Files with no reviewable changes (1)
  • .github/workflows/employment-employing-organization-quality.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • manifest.json

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Employment와 법적 고용 조직의 bitemporal 관계를 추가했습니다. API 요청과 권한 검사를 확장했습니다. People 및 confirmed-hire 저장 경로에서 active/leave 고용의 관계를 기록합니다. PostgreSQL 계약 테스트와 CI 검증을 추가했습니다.

Changes

고용주 관계 계약

Layer / File(s) Summary
고용주 관계 스키마와 계약
database/migrations/0040_employment_employing_organization.sql, docs/DATA_MODEL.md, docs/ERD.md, docs/adr/0141-employment-employing-organization.md, docs/doctoring/employment-employing-organization.md, schemas/openapi.yaml, docs/API_CONTRACT.md, docs/SECURITY.md
employment_employing_organization_record와 bitemporal 제약, 정확히 하나의 법적 고용주 검증, 이력 보호 및 테넌트 RLS를 추가했습니다. API 계약과 데이터 모델 문서를 갱신했습니다.
고용 및 채용 쓰기 경로
services/people-api/src/orgmetra_people_api/{authorization.py,hire.py,hire_http.py,mutation_http.py,mutations.py,postgres_hire.py,postgres_mutations.py}, packages/keyverse-adapter/src/orgmetra_keyverse_adapter/authorization.py
고용 조직 식별자와 관계 레코드 식별자를 명령에 추가했습니다. 정확한 조직 단위 target scope를 인가하고, active 또는 leave 상태에서 관계를 같은 트랜잭션에 저장합니다.
데이터베이스 및 API 검증
services/people-api/tests/*, packages/keyverse-adapter/tests/*, tests/test_employment_employing_organization_postgres.sh, tests/test_operational_uuid_postgres.sh, tests/foundation-contract.test.mjs
정확히 하나의 고용주, 법인 범위, 테넌트 격리, terminated 예외, target scope 거부, UUID 검증 및 요청 필드 계약을 검증합니다.
저장소 계약과 CI 실행
.github/workflows/employment-employing-organization-quality.yml, scripts/foundation-contract-core.mjs, tests/validate_repository.py, package.json, manifest.json, CHANGELOG.md, docs/adr/README.md
필수 파일과 데이터베이스 객체 검증을 갱신했습니다. 고용주 계약 검증 명령과 PostgreSQL 품질 workflow를 추가했습니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: 🟠 High · up to 48de1

The PR adds authoritative employing-organization writes, but authorization evidence is not bound to the exact organization used at persistence, creating a potential same-tenant legal-employer substitution path across employment and hire flows. Required independent review and security-gate evidence is also incomplete, so the PR is not merge-ready.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant PeopleAPI
  participant Keyverse
  participant PostgreSQL
  Client->>PeopleAPI: 고용 또는 confirmed-hire 요청
  PeopleAPI->>Keyverse: operation scope 및 target scope 평가
  Keyverse-->>PeopleAPI: 인가 결정 반환
  PeopleAPI->>PostgreSQL: Employment와 고용주 관계 저장
  PostgreSQL-->>PeopleAPI: deferred 계약 검증 및 커밋
  PeopleAPI-->>Client: 결과 반환
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.94% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 64 functions across 31 files. (2 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 Employment를 법적 고용 조직에 연결하는 주요 변경 사항을 정확하고 간결하게 설명합니다.
Full details: Docstring Coverage

Explanation

Docstring coverage is 60.94% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 64 functions across 31 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/employment-employing-organization

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae
seonghobae marked this pull request as draft August 28, 2026 01:06
devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

github-code-quality[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode reviewed the current-head product diff. Coverage is a separate gate.

Changed files

  • .github/workflows/employment-employing-organization-quality.yml — GitHub Actions review job
  • CHANGELOG.md — repository behavior
  • database/migrations/0040_employment_employing_organization.sql — repository behavior
  • docs/API_CONTRACT.md — operator or user guidance
  • docs/DATA_MODEL.md — operator or user guidance
  • docs/ERD.md — operator or user guidance
  • docs/SECURITY.md — operator or user guidance
  • docs/TRACEABILITY.md — operator or user guidance
  • docs/adr/0141-employment-employing-organization.md — operator or user guidance
  • docs/adr/README.md — operator or user guidance
  • docs/doctoring/employment-employing-organization.md — operator or user guidance
  • manifest.json — repository behavior
  • package.json — repository behavior
  • packages/keyverse-adapter/src/orgmetra_keyverse_adapter/authorization.py — Python module behavior
  • packages/keyverse-adapter/tests/test_authorization.py — regression suite
  • packages/keyverse-adapter/tests/test_target_scope_denial_guidance.py — regression suite
  • schemas/openapi.yaml — repository behavior
  • scripts/foundation-contract-core.mjs — TypeScript or JavaScript runtime
  • services/people-api/src/orgmetra_people_api/authorization.py — Python module behavior
  • services/people-api/src/orgmetra_people_api/hire.py — Python module behavior
  • services/people-api/src/orgmetra_people_api/hire_http.py — Python module behavior
  • services/people-api/src/orgmetra_people_api/mutation_http.py — Python module behavior
  • services/people-api/src/orgmetra_people_api/mutations.py — Python module behavior
  • services/people-api/src/orgmetra_people_api/postgres_hire.py — Python module behavior
  • services/people-api/src/orgmetra_people_api/postgres_mutations.py — Python module behavior
  • services/people-api/tests/test_decision_reason_binding.py — regression suite
  • services/people-api/tests/test_employing_organization_authorization_binding.py — regression suite
  • services/people-api/tests/test_evidence_reference_binding_regression.py — regression suite
  • services/people-api/tests/test_hire_acceptance.py — regression suite
  • services/people-api/tests/test_hire_http_route.py — regression suite
  • services/people-api/tests/test_hire_http_scalar_contract.py — regression suite
  • services/people-api/tests/test_mutation_http_authentication_order.py — regression suite
  • services/people-api/tests/test_mutation_http_route.py — regression suite
  • services/people-api/tests/test_mutation_http_schema_types.py — regression suite
  • services/people-api/tests/test_people_mutations.py — regression suite
  • services/people-api/tests/test_postgres_hire_acceptance.py — regression suite
  • services/people-api/tests/test_postgres_people_mutations.py — regression suite
  • services/people-api/tests/test_review_regressions.py — regression suite
  • services/people-api/tests/test_support_reference_correlation.py — regression suite
  • services/people-api/tests/test_support_reference_response_privacy.py — regression suite
  • tests/foundation-contract.test.mjs — regression suite
  • tests/test_employment_employing_organization_postgres.sh — regression suite
  • tests/test_operational_uuid_postgres.sh — regression suite
  • tests/validate_repository.py — regression suite

Changed behavior

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow: employment-employing-organization-quality.yml"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> R1["Review risk: Workflow: employment-employing-organization-quality.yml"]
  R1 --> V1["actionlint plus required checks"]
  Evidence --> S2["Repository file: CHANGELOG.md"]
  S2 --> I2["repository behavior"]
  I2 --> R2["Review risk: Repository file: CHANGELOG.md"]
  R2 --> V2["required checks"]
  Evidence --> S3["Repository file: 0040_employment_employing_organization.sql"]
  S3 --> I3["repository behavior"]
  I3 --> R3["Review risk: Repository file: 0040_employment_employing_organization.sql"]
  R3 --> V3["required checks"]
  Evidence --> S4["Docs: API_CONTRACT.md (8 files)"]
  S4 --> I4["operator or user guidance"]
  I4 --> R4["Review risk: Docs: API_CONTRACT.md (8 files)"]
  R4 --> V4["docs review"]
  Evidence --> S5["Repository file: manifest.json"]
  S5 --> I5["repository behavior"]
  I5 --> R5["Review risk: Repository file: manifest.json"]
  R5 --> V5["required checks"]
  Evidence --> S6["Repository file: package.json"]
  S6 --> I6["repository behavior"]
  I6 --> R6["Review risk: Repository file: package.json"]
  R6 --> V6["required checks"]
  Evidence --> S7["Python: authorization.py (8 files)"]
  S7 --> I7["Python module behavior"]
  I7 --> R7["Review risk: Python: authorization.py (8 files)"]
  R7 --> V7["pytest plus coverage"]
  Evidence --> S8["Test: test_authorization.py (2 files)"]
  S8 --> I8["regression suite"]
  I8 --> R8["Review risk: Test: test_authorization.py (2 files)"]
  R8 --> V8["targeted test run"]
  Evidence --> S9["Repository file: openapi.yaml"]
  S9 --> I9["repository behavior"]
  I9 --> R9["Review risk: Repository file: openapi.yaml"]
  R9 --> V9["required checks"]
  Evidence --> S10["TypeScript/JavaScript: foundation-contract-core.mjs"]
  S10 --> I10["TypeScript or JavaScript runtime"]
  I10 --> R10["Review risk: TypeScript/JavaScript: foundation-contract-core.mjs"]
  R10 --> V10["package test plus coverage"]
  Evidence --> S11["Test: test_decision_reason_binding.py (15 files)"]
  S11 --> I11["regression suite"]
  I11 --> R11["Review risk: Test: test_decision_reason_binding.py (15 files)"]
  R11 --> V11["targeted test run"]
  Evidence --> S12["Test: foundation-contract.test.mjs (4 files)"]
  S12 --> I12["regression suite"]
  I12 --> R12["Review risk: Test: foundation-contract.test.mjs (4 files)"]
  R12 --> V12["targeted test run"]
Loading

Findings

No source-backed product finding is synthesized from the coverage gate. A coverage miss belongs in the status comment.

  • Head SHA: 8d12ee7cd05549a69c6debf5e0de0c5fc8668f33
  • Workflow run: 33242513434
  • Workflow attempt: 1
  • Coverage gate: failure

Review outcome

Coverage is a gate, not the review. This body reviews the changed product files.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow: employment-employing-organization-quality.yml"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> R1["Review risk: Workflow: employment-employing-organization-quality.yml"]
  R1 --> V1["actionlint plus required checks"]
  Evidence --> S2["Repository file: CHANGELOG.md"]
  S2 --> I2["repository behavior"]
  I2 --> R2["Review risk: Repository file: CHANGELOG.md"]
  R2 --> V2["required checks"]
  Evidence --> S3["Repository file: 0040_employment_employing_organization.sql"]
  S3 --> I3["repository behavior"]
  I3 --> R3["Review risk: Repository file: 0040_employment_employing_organization.sql"]
  R3 --> V3["required checks"]
  Evidence --> S4["Docs: API_CONTRACT.md (8 files)"]
  S4 --> I4["operator or user guidance"]
  I4 --> R4["Review risk: Docs: API_CONTRACT.md (8 files)"]
  R4 --> V4["docs review"]
  Evidence --> S5["Repository file: manifest.json"]
  S5 --> I5["repository behavior"]
  I5 --> R5["Review risk: Repository file: manifest.json"]
  R5 --> V5["required checks"]
  Evidence --> S6["Repository file: package.json"]
  S6 --> I6["repository behavior"]
  I6 --> R6["Review risk: Repository file: package.json"]
  R6 --> V6["required checks"]
  Evidence --> S7["Python: authorization.py (8 files)"]
  S7 --> I7["Python module behavior"]
  I7 --> R7["Review risk: Python: authorization.py (8 files)"]
  R7 --> V7["pytest plus coverage"]
  Evidence --> S8["Test: test_authorization.py (2 files)"]
  S8 --> I8["regression suite"]
  I8 --> R8["Review risk: Test: test_authorization.py (2 files)"]
  R8 --> V8["targeted test run"]
  Evidence --> S9["Repository file: openapi.yaml"]
  S9 --> I9["repository behavior"]
  I9 --> R9["Review risk: Repository file: openapi.yaml"]
  R9 --> V9["required checks"]
  Evidence --> S10["TypeScript/JavaScript: foundation-contract-core.mjs"]
  S10 --> I10["TypeScript or JavaScript runtime"]
  I10 --> R10["Review risk: TypeScript/JavaScript: foundation-contract-core.mjs"]
  R10 --> V10["package test plus coverage"]
  Evidence --> S11["Test: test_decision_reason_binding.py (15 files)"]
  S11 --> I11["regression suite"]
  I11 --> R11["Review risk: Test: test_decision_reason_binding.py (15 files)"]
  R11 --> V11["targeted test run"]
  Evidence --> S12["Test: foundation-contract.test.mjs (4 files)"]
  S12 --> I12["regression suite"]
  I12 --> R12["Review risk: Test: foundation-contract.test.mjs (4 files)"]
  R12 --> V12["targeted test run"]
Loading

@opencode-agent

opencode-agent Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

Coverage evidence did not pass, so approval is blocked. The formal pull-request review is the source-backed diff review, not this status comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant